package com.haixiaoke.saas.contract.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasc.open.api.v5_1.req.signtask.AddFillFieldInfo;
import com.fasc.open.api.v5_1.res.template.FillActorFieldInfo;
import com.fasc.open.api.v5_1.res.template.SignTaskActorInfo;
import com.fasc.open.api.v5_1.res.template.SignTemplateDetailRes;
import com.haixiaoke.saas.bill.service.IProprietorBillService;
import com.haixiaoke.saas.common.constant.*;
import com.haixiaoke.saas.common.core.domain.AjaxResult;
import com.haixiaoke.saas.common.electronicVisa.domain.ElectronicVisaContract;
import com.haixiaoke.saas.common.enums.HouseStateEnum;
import com.haixiaoke.saas.common.enums.ProprietorContractEnum;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.tenant.TenantContext;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.PlaceholderUtil;
import com.haixiaoke.saas.contract.domain.*;
import com.haixiaoke.saas.contract.fadada.service.FaDaDaService;
import com.haixiaoke.saas.contract.mapper.ProprietorContractMapper;
import com.haixiaoke.saas.contract.service.*;
import com.haixiaoke.saas.department.domain.ElectronicVisa;
import com.haixiaoke.saas.department.domain.ElectronicVisaSignProgress;
import com.haixiaoke.saas.department.domain.Tenant;
import com.haixiaoke.saas.department.service.IElectronicVisaService;
import com.haixiaoke.saas.department.service.IElectronicVisaSignProgressService;
import com.haixiaoke.saas.department.service.ITenantService;
import com.haixiaoke.saas.house.domain.Estate;
import com.haixiaoke.saas.house.domain.House;
import com.haixiaoke.saas.house.domain.HouseOperatingRecord;
import com.haixiaoke.saas.house.domain.Unit;
import com.haixiaoke.saas.house.service.IEstateService;
import com.haixiaoke.saas.house.service.IHouseOperatingRecordService;
import com.haixiaoke.saas.house.service.IHouseService;
import com.haixiaoke.saas.house.service.IUnitService;
import com.haixiaoke.saas.user.domain.BizUserBusiness;
import com.haixiaoke.saas.user.domain.UserConsumer;
import com.haixiaoke.saas.user.service.IBizUserBusinessService;
import com.haixiaoke.saas.user.service.IUserConsumerService;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业主合同管理Service业务层处理
 *
 * @author xiaolong
 * @date 2024-05-27
 */
@Service
public class ProprietorContractServiceImpl implements IProprietorContractService {
    @Autowired
    private ProprietorContractMapper proprietorContractMapper;
    @Autowired
    private IHouseService houseService;
    @Autowired
    private IHouseOperatingRecordService houseOperatingRecordService;
    @Autowired
    private IBizUserBusinessService bizUserBusinessService;
    @Autowired
    private IEstateService estateService;
    @Autowired
    private IUserConsumerService userConsumerService;
    @Autowired
    private FaDaDaService faDaDaService;
    @Autowired
    private IContractTemplateService contractTemplateService;
    @Autowired
    private IUnitService unitService;
    @Autowired
    private IProprietorService proprietorService;
    @Autowired
    private IHouseCommissionService houseCommissionService;
    @Autowired
    private IProxyServiceService proxyServiceService;
    @Autowired
    private IElectronicVisaService electronicVisaService;
    @Autowired
    private IElectronicVisaSignProgressService electronicVisaSignProgressService;
    @Autowired
    private ITenantService tenantService;
    @Autowired
    private IProprietorBillService propertiesBillService;

    /**
     * 查询业主合同管理
     *
     * @param proprietorContractId 业主合同管理主键
     * @return 业主合同管理
     */
    @Override
    public ProprietorContract selectProprietorContractByProprietorContractId(String proprietorContractId) {
        return proprietorContractMapper.selectProprietorContractByProprietorContractId(proprietorContractId);
    }

    /**
     * 查询业主合同管理列表
     *
     * @param proprietorContract 业主合同管理
     * @return 业主合同管理
     */
    @Override
    public List<ProprietorContract> selectProprietorContractList(ProprietorContract proprietorContract) {
        return proprietorContractMapper.selectProprietorContractList(proprietorContract);
    }

    /**
     * 新增业主合同管理
     *
     * @param proprietorContract 业主合同管理
     * @return 结果
     */
    @Override
    @Transactional
    public int insertProprietorContract(ProprietorContract proprietorContract) {
        Date nowDate = DateUtils.getNowDate();
        House house = proprietorContract.getHouse();
        String houseId = "H" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        String proprietorContractId = "PC" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        house.setHouseId(houseId);
        packagingData(house);
        dataCheck(proprietorContract);
        house.setCreateTime(nowDate);
        Unit unit = unitService.selectUnitByUnitId(house.getUnitId());
        if (ObjectUtil.isEmpty(unit)) {
            throw new ServiceException("单元不存在");
        }
        Proprietor proprietor = proprietorService.selectProprietorByConUserId(house.getProprietorUserId());
        if (ObjectUtil.isEmpty(proprietor)) {
            throw new ServiceException("业主不存在");
        }

        // 业主合同是签署中不展示房间信息
        house.setDelFlag(Constants.DEL_FLAG_NO);
        int i = houseService.insertHouseInfo(house);
        // 记录操作记录
        if (i != 0) {
            HouseOperatingRecord record = new HouseOperatingRecord();
            record.setHouseId(houseId);
            record.setOperatingRecordContent("创建了房屋信息");
            record.setOperatingRecordType(HouseOperatingRecord.OPERATING_RECORD_TYPE_ONE);
            record.setOperatingRecordId(house.getBizUserBusiness().getUserId());
            record.setOperatingRecordName(house.getBizUserBusiness().getUserName());
            record.setOperatingRecordPhone(house.getBizUserBusiness().getPhonenumber());
            houseOperatingRecordService.insertHouseOperatingRecord(record);
        }

        List<ElectronicVisaSignProgress> signProgressList = new ArrayList<>();

        if (ContractConstants.SIGNING_MODE_ELECTRONIC.equals(proprietorContract.getSigningMode())) {
            //电子合同
            Tenant tenant = tenantService.selectDepByDepId(proprietorContract.getTenantId());
            if (TenantConstants.ELECTRONIC_VISA_STATUS_UN_OPEN.equals(tenant.getElectronicVisaStatus())) {
                throw new ServiceException("电子合同未开通,请去管理端开通电子合同");
            }
            ElectronicVisa electronicVisa = electronicVisaService.selectElectronicVisaByTenantId(proprietorContract.getTenantId());
            if (ObjectUtil.isNull(electronicVisa)) {
                throw new ServiceException("电子签证信息不存在");
            }
            if (ObjectUtil.isNotEmpty(electronicVisa) &&
                    TenantConstants.ELECTRONIC_VISA_TYPE_ENTERPRISE.equals(electronicVisa.getElectronicVisaType())
                    && electronicVisa.getContractLeftNumber() <= 0) {
                throw new ServiceException("电子合用余额不足,请购买电子合同用量");
            }
            // 封装签署任务数据
            ElectronicVisaSignProgress proprietorSignProgress = new ElectronicVisaSignProgress();
            proprietorSignProgress.setSigner(proprietor.getProprietorName());
            proprietorSignProgress.setSignType(TenantConstants.SIGN_TYPE_PARTY_B);
            ElectronicVisaSignProgress initiatorSignProgress = new ElectronicVisaSignProgress();
            initiatorSignProgress.setSigner(electronicVisa.getOrganizationName());
            initiatorSignProgress.setSignType(TenantConstants.SIGN_TYPE_PARTY_A);
            signProgressList.add(proprietorSignProgress);
            signProgressList.add(initiatorSignProgress);

            // 电子签
            SignTemplateDetailRes signTemplateDetail = faDaDaService.getSignTemplateDetail(proprietorContract.getContractTemplateId());
            List<AddFillFieldInfo> list = new ArrayList<>();
            List<SignTaskActorInfo> actors = signTemplateDetail.getActors();
            for (SignTaskActorInfo actor : actors) {
                List<FillActorFieldInfo> fillFields = actor.getFillFields();
                if (CollectionUtil.isNotEmpty(fillFields)) {
                    for (FillActorFieldInfo fillField : fillFields) {
                        AddFillFieldInfo info = new AddFillFieldInfo();
                        info.setFieldDocId(fillField.getFieldDocId().toString());
                        info.setFieldValue(buildValue(fillField.getFieldId(), proprietorContract, house, electronicVisa, proprietor));
                        info.setFieldId(fillField.getFieldId());
                        info.setFieldName(faDaDaService.buildFieldName(fillField.getFieldId()));
                        list.add(info);
                    }
                }
            }
            ElectronicVisaContract electronicVisaContract = buildElectronicVisaContract(list, proprietorContract, house, electronicVisa, proprietor);
            // 签署任务id
            String signTaskId = faDaDaService.createWithTemplate(electronicVisaContract);
            proprietorContract.setFlowId(signTaskId);


            // 插入签署进度
            signProgressList.forEach(progress -> {
                progress.setContractId(proprietorContractId);
                progress.setSignProgress(TenantConstants.SIGN_PROGRESS_UNSIGNED);
                progress.setContractType(TenantConstants.CONTRACT_TYPE_PROPRIETOR);
                progress.setCreateTime(nowDate);
                progress.setCreateBy(proprietorContract.getCreateBy());
                progress.setTenantId(proprietorContract.getTenantId());
            });
            electronicVisaSignProgressService.insertBatchElectronicVisaSignProgress(signProgressList);

            //更新电子签状态
            electronicVisaService.subtractVisaContractNumber(electronicVisa.getVisaId());
        } else if (ContractConstants.SIGNING_MODE_PAPER.equals(proprietorContract.getSigningMode())) {
            //纸质合同
            ContractTemplate contractTemplate = contractTemplateService.selectContractTemplateByContractTemplateId(proprietorContract.getContractTemplateId());
            if (ObjectUtil.isEmpty(contractTemplate)) {
                throw new ServiceException("合同模板不存在");
            }
            if (ContractConstants.TEMPLATE_STATE_CONCEAL.equals(contractTemplate.getTemplateState())) {
                throw new ServiceException("合同模板已被隐藏");
            }
            if (!((ContractConstants.TEMPLATE_TYPE_HOUSE_COMMISSION.equals(contractTemplate.getTemplateType()) &&
                    ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType()))
                    || (ContractConstants.TEMPLATE_TYPE_SERVICE.equals(contractTemplate.getTemplateType()) &&
                    ContractConstants.COOPERATION_TYPE_AGENCY_SERVICE.equals(house.getCooperationType())))) {
                throw new ServiceException("合同类型和合同模板类型不匹配");
            }
            // 创建合同具体数据
            Map<String, Object> map = buildContractParameter(house, proprietorContract, unit, proprietor);

            String content = PlaceholderUtil.format(contractTemplate.getTemplateContent(), map, "");
            if (StrUtil.isBlank(content)) {
                throw new ServiceException("合同内容生成错误");
            }

            // 封装纸质合同内容数据
            proprietorContract.setTemplateContent(contractTemplate.getTemplateContent());
            proprietorContract.setContractContent(content);
        }
        proprietorContract.setProprietorContractId(proprietorContractId);
        proprietorContract.setHouseId(houseId);
        proprietorContract.setCreateTime(DateUtils.getNowDate());
        proprietorContract.setContractStatus(ProprietorContractEnum.CONTRACT_STATUS_SIGN.getValue());
        proprietorContract.setProprietorUserId(house.getProprietorUserId());
        return proprietorContractMapper.insertProprietorContract(proprietorContract);
    }

    /**
     * @param list           合同组件信息
     * @param house          房屋信息
     * @param electronicVisa 电子签信息
     * @return
     */
    private ElectronicVisaContract buildElectronicVisaContract(List<AddFillFieldInfo> list,
                                                               ProprietorContract proprietorContract, House house,
                                                               ElectronicVisa electronicVisa, Proprietor proprietor) {
        ElectronicVisaContract electronicVisaContract = new ElectronicVisaContract();
        electronicVisaContract.setTemplateId(proprietorContract.getContractTemplateId());
        electronicVisaContract.setName(proprietor.getProprietorName());
        electronicVisaContract.setMobile(proprietor.getProprietorMobile());
        electronicVisaContract.setIdCard(proprietor.getCardNumber());
        electronicVisaContract.setActorCorporateName(proprietor.getProprietorName());
        electronicVisaContract.setActorSocialCreditCode(proprietor.getSocialCreditCode());
        electronicVisaContract.setFillFieldList(list);
        electronicVisaContract.setOpenId(electronicVisa.getOpenId());
        electronicVisaContract.setProxyOperatorOpenid(electronicVisa.getProxyOperatorOpenid());
        electronicVisaContract.setActorName(electronicVisa.getOrganizationName());
        electronicVisaContract.setExpiresTime(proprietorContract.getLatestSigningDate());
        electronicVisaContract.setPartyType(false);
        electronicVisaContract.setActorPartyType(ContractConstants.PROPRIETOR_TYPE_PERSON.equals(proprietor.getProprietorType()));
        return electronicVisaContract;
    }

    /**
     * 封装电子合同参数
     *
     * @param fieldId
     * @return
     */
    private String buildValue(String fieldId, ProprietorContract contract, House house,
                              ElectronicVisa electronicVisa, Proprietor proprietor) {
        /*HouseCommission houseCommission = null;
        ProxyService proxyService = null;
        if (ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType())) {
            houseCommission = houseCommissionService.selectHouseCommissionByProprietorId(proprietor.getProprietorId());
        } else if (ContractConstants.COOPERATION_TYPE_AGENCY_SERVICE.equals(house.getCooperationType())) {
            proxyService = proxyServiceService.selectProxyServiceByProprietorId(proprietor.getProprietorId());
        }*/
        String fieldValue = "";
        switch (fieldId) {
            case TencentContractTemplateModule.HOUSE_ADDRESS:
                fieldValue = house.getPremisesAddress();
                break;
            case TencentContractTemplateModule.ORG_NAME:
                fieldValue = electronicVisa.getOrganizationName();
                break;
            case TencentContractTemplateModule.USCC:
                fieldValue = electronicVisa.getSocialCreditCode();
                break;

            case TencentContractTemplateModule.HOUSE_TYPE:
                String houseType = "";
                String room = house.getRoomType();
                String hall = house.getHall();
                String toilet = house.getToilet();
                if (StrUtil.isNotBlank(room)) {
                    houseType += room + "室";
                }
                if (StrUtil.isNotBlank(hall)) {
                    houseType += hall + "厅";
                }
                if (StrUtil.isNotBlank(toilet)) {
                    houseType += toilet + "卫";
                }
                fieldValue = houseType;
                break;
            case TencentContractTemplateModule.AREA:
                fieldValue = house.getHouseArea() + "m²";
                break;
            case TencentContractTemplateModule.USER_NAME:
                fieldValue = proprietor.getProprietorName();
                break;
            case TencentContractTemplateModule.ID_CARD:
                fieldValue = proprietor.getCardNumber();
                break;
            case TencentContractTemplateModule.LEASE_START_TIME:
                if (ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType())) {
                    //房屋委托合同
                    fieldValue = DateUtil.format(contract.getLeaseStartDate(), "yyyy-MM-dd");
                } else {
                    fieldValue = "";
                }
                break;
            case TencentContractTemplateModule.LEASE_END_TIME:
                if (ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType())) {
                    //房屋委托合同
                    fieldValue = DateUtil.format(contract.getLeaseEndDate(), "yyyy-MM-dd");
                } else {
                    fieldValue = "";
                }
                break;
            case TencentContractTemplateModule.RENT:
                if (ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType())) {
                    //房屋委托合同
                    fieldValue = contract.getMonthRent().toString();
                } else {
                    fieldValue = "";
                }
                break;
            case TencentContractTemplateModule.CASH_PLEDGE:
                if (ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType())) {
                    //房屋委托合同
                    fieldValue = contract.getCashPledge().toString();
                } else {
                    fieldValue = "";
                }
                break;
            case TencentContractTemplateModule.PAYMENT_DATE:
                if (ContractConstants.COOPERATION_TYPE_AGENCY_SERVICE.equals(house.getCooperationType()) &&
                        HouseConstants.CHARGE_TYPE_DISPOSABLE.equals(house.getChargeType())) {
                    //代理服务合同
                    fieldValue = DateUtil.format(house.getLatestPaymentDate(), "yyyy-MM-dd");
                }
                break;
            case TencentContractTemplateModule.ADDITIONAL_TERMS:
                fieldValue = "无";
            default:
                break;
        }
        return fieldValue;
    }

    private Map<String, Object> buildContractParameter(House house, ProprietorContract contract, Unit unit, Proprietor proprietor) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        ContractParameter parameter = new ContractParameter();
        //合同编号
        parameter.setContractId(contract.getContractNumber());
        //城市名
        parameter.setCity(house.getCityName());
        // 房屋地址(楼盘+楼栋+单元+门牌号)
        parameter.setHouseAddress(house.getPremisesAddress());
        // 户型(几室几厅几卫)
        parameter.setHouseType(house.getRoomType() + "室" + house.getHall() + "厅" + house.getToilet() + "卫");
        // 楼层
        parameter.setFloor(String.valueOf(house.getFloors()));
        // 总楼层
        parameter.setTotalFloor(String.valueOf(unit.getFloors()));
        // 房屋面积
        parameter.setHouseArea(house.getHouseArea() + "m²");
        if (ContractConstants.COOPERATION_TYPE_HOUSE_COMMISSION.equals(house.getCooperationType())) {
            //房屋委托合同
            // 租住起始日期
            parameter.setStartDate(sdf.format(contract.getLeaseStartDate()));
            // 租住结束日期
            parameter.setEndDate(sdf.format(contract.getLeaseEndDate()));
            // 租金(房费金额)
            parameter.setRentAmount(contract.getMonthRent() + "元/月");
            //押金
            parameter.setDepositAmount(contract.getCashPledge() + "元");
            HouseCommission houseCommission = houseCommissionService.selectHouseCommissionByProprietorId(proprietor.getProprietorId());
            if (ObjectUtil.isNotEmpty(houseCommission)) {
                //开户人
                parameter.setAccountHolder(houseCommission.getAccountHolder());
                //银行账号
                parameter.setBankAccount(houseCommission.getBankAccount());
                //开户银行
                parameter.setBankName(houseCommission.getBankName());
                //银行支行
                parameter.setBankBranch(houseCommission.getBankBranch());
            }
        } else if (ContractConstants.COOPERATION_TYPE_AGENCY_SERVICE.equals(house.getCooperationType())) {
            //代理服务合同
            //服务期限
            StringBuilder servicePeriod = new StringBuilder();
            if (contract.getServicePeriodYear() > 0) {
                servicePeriod.append(contract.getServicePeriodYear()).append("年");
            }
            if (contract.getServicePeriodMonth() > 0) {
                servicePeriod.append(contract.getServicePeriodMonth()).append("月");
            }
            parameter.setServicePeriod(servicePeriod.toString());
            //筹备期
            parameter.setPreparationPeriod(contract.getPreparatoryPeriod() + "天");
            //收费方式
            if (HouseStateEnum.CHARGE_TYPE_BILL.getValue().equals(house.getChargeType())) {
                //账单服务费
                parameter.setBillingServiceFee(house.getServiceCharge() + "%");
            } else if (HouseStateEnum.CHARGE_TYPE_DISPOSABLE.getValue().equals(house.getChargeType())) {
                //一次性付款
//                parameter.setBillingServiceFee("");
            }
            //开户人
            parameter.setAccountHolder(proprietor.getProprietorName());
            ProxyService proxyService = proxyServiceService.selectProxyServiceByProprietorId(proprietor.getProprietorId());
            if (ObjectUtil.isNotEmpty(proxyService)) {
                //银行账号
                parameter.setBankAccount(proxyService.getBankAccount());
                //开户银行
                parameter.setBankName(proxyService.getBankName());
                //银行支行
                parameter.setBankBranch(proxyService.getBankBranch());
            }
        }
        // 生成纸质合同内容数据
        return BeanUtil.beanToMap(parameter);
    }

    private void dataCheck(ProprietorContract proprietorContract) {
        if (ProprietorContractEnum.COOPERATION_TYPE_COMMISSION.getValue().equals(proprietorContract.getCooperationType())) {
            if (proprietorContract.getLeaseStartDate() == null || proprietorContract.getLeaseEndDate() == null || proprietorContract.getCashPledge() == null || proprietorContract.getMonthRent() == null) {
                throw new ServiceException("请输入数据");
            }
            if (proprietorContract.getLeaseEndDate().before(proprietorContract.getLeaseStartDate())) {
                throw new ServiceException("租赁期限的开始时间不能大于结束时间");
            }
            if (proprietorContract.getCashPledge().scale() > 2) {
                throw new ServiceException("押金最多小数点后两位");
            }
            if (proprietorContract.getMonthRent().scale() > 2) {
                throw new ServiceException("租金最多小数点后两位");
            }
        } else {
            if (proprietorContract.getPreparatoryPeriod() == null || proprietorContract.getServicePeriodMonth() == null || proprietorContract.getServicePeriodYear() == null) {
                throw new ServiceException("请输入数据");
            }
            if (proprietorContract.getPreparatoryPeriod() < 0) {
                throw new ServiceException("筹备期需是正数");
            }
            if (proprietorContract.getServicePeriodMonth() < 0 || proprietorContract.getServicePeriodYear() < 0) {
                throw new ServiceException("服务期限需是正数");
            }
        }
    }

    /**
     * 修改业主合同管理
     *
     * @param proprietorContract 业主合同管理
     * @return 结果
     */
    @Override
    public int updateProprietorContract(ProprietorContract proprietorContract) {
        proprietorContract.setUpdateTime(DateUtils.getNowDate());
        return proprietorContractMapper.updateProprietorContract(proprietorContract);
    }

    /**
     * 批量删除业主合同管理
     *
     * @param proprietorContractIds 需要删除的业主合同管理主键
     * @return 结果
     */
    @Override
    public int deleteProprietorContractByProprietorContractIds(String[] proprietorContractIds) {
        ProprietorContract proprietorContract = new ProprietorContract();
        proprietorContract.setTenantId(TenantContext.getTenantId());
        proprietorContract.setProprietorContractIds(proprietorContractIds);
        List<ProprietorContract> proprietorContractList = proprietorContractMapper.selectProprietorContractByProprietorContractIds(proprietorContract);
        if (proprietorContractList.size() < proprietorContractIds.length) {
            return 0;
        }
        return proprietorContractMapper.deleteProprietorContractByProprietorContractIds(proprietorContractIds);
    }

    /**
     * 删除业主合同管理信息
     *
     * @param proprietorContractId 业主合同管理主键
     * @return 结果
     */
    @Override
    public int deleteProprietorContractByProprietorContractId(String proprietorContractId) {
        return proprietorContractMapper.deleteProprietorContractByProprietorContractId(proprietorContractId);
    }

    @Override
    public List<UserConsumer> selectProprietorInfo() {
        return userConsumerService.selectProprietorInfo();
    }

    @Override
    public List<ProprietorContract> selectProprietorContractByProprietorUserId(ProprietorContract proprietorContract) {
        return proprietorContractMapper.selectProprietorContractByProprietorUserId(proprietorContract);
    }

    @Override
    public int updateProprietorContractByProprietorContractId(String proprietorContractId) {
        ProprietorContract proprietorContract = proprietorContractMapper.selectProprietorContractByProprietorContractId(proprietorContractId);
        if (ObjectUtil.isEmpty(proprietorContract)) {
            throw new ServiceException("合同不存在");
        }
        if (ProprietorContractEnum.CONTRACT_STATUS_SIGN.getValue().equals(proprietorContract.getContractStatus())) {
            throw new ServiceException("合同状态不正确");
        }
        return proprietorContractMapper.updateProprietorContractByProprietorContractId(proprietorContractId);
    }

    @Override
    public String selectProprietorContractElectronicVisaPreviewUrl(ProprietorContract proprietorContract) {
        ProprietorContract contract = proprietorContractMapper.selectProprietorContractByProprietorContractId(proprietorContract.getProprietorContractId());
        if (ObjectUtil.isNotEmpty(contract) && ContractConstants.SIGNING_MODE_ELECTRONIC.equals(contract.getSigningMode())) {
            return faDaDaService.getSignTaskPreviewUrl(contract.getFlowId(), proprietorContract.getRedirectUrl());
        }
        return null;
    }

    @Override
    @Transactional
    public AjaxResult uploadContractImage(ProprietorContract proprietorContract) {
        if (CollectionUtil.isEmpty(proprietorContract.getContractImageList())) {
            return AjaxResult.error("请上传图片");
        }
        ProprietorContract contract = proprietorContractMapper.selectProprietorContractByProprietorContractId(proprietorContract.getProprietorContractId());

        if (ObjectUtil.isNotEmpty(contract)) {
            if (ContractConstants.SIGNING_MODE_ELECTRONIC.equals(contract.getSigningMode())) {
                return AjaxResult.error("电子合同不支持上传图片");
            }
            if (proprietorContract.getContractImageList().size() > 30) {
                return AjaxResult.error("合同图片不能超过30张");
            }
            proprietorContract.setContractImage(StringUtils.join(proprietorContract.getContractImageList(), ","));
            proprietorContract.setContractStatus(ProprietorContractEnum.CONTRACT_STATUS_FINISH.getValue());
            proprietorContract.setUpdateTime(DateUtils.getNowDate());

            // 合同签署完,更新房屋状态为未删除
            houseService.updateHouseByDelFlag(contract.getHouseId());

            // 业主账单插入
            propertiesBillService.insertProprietorBillByHouse(contract.getHouseId());
            return proprietorContractMapper.updateProprietorContract(proprietorContract) > 0 ? AjaxResult.success() : AjaxResult.error();
        }
        return AjaxResult.error("合同不存在");
    }

    @Override
    public AjaxResult repealProprietorContract(ProprietorContract proprietorContract) {
        ProprietorContract contract = proprietorContractMapper.selectProprietorContractByProprietorContractId(proprietorContract.getProprietorContractId());
        if (ObjectUtil.isEmpty(contract)) {
            return AjaxResult.error("合同不存在");
        }
        if (!(ProprietorContractEnum.CONTRACT_STATUS_SIGN.getValue().equals(contract.getContractStatus()))) {
            return AjaxResult.error("合同状态异常，请刷新后再试");
        }
        if (ContractConstants.SIGNING_MODE_ELECTRONIC.equals(contract.getSigningMode())) {
            // 电子合同，调用撤销接口取消合同
            faDaDaService.cancel(contract.getFlowId());
        } else if (ContractConstants.SIGNING_MODE_PAPER.equals(contract.getSigningMode())) {
            // 纸质合同，直接更新状态为终止
            proprietorContract.setContractStatus(ProprietorContractEnum.CONTRACT_STATUS_TERMINATION.getValue());
            proprietorContract.setUpdateTime(DateUtils.getNowDate());
            proprietorContractMapper.updateProprietorContract(proprietorContract);
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult signingLesseeContract(ProprietorContract proprietorContract, Long conUserId) {
        ProprietorContract contract = proprietorContractMapper.selectProprietorContractByProprietorContractId(proprietorContract.getProprietorContractId());
        if (ObjectUtil.isEmpty(contract)) {
            return AjaxResult.error("合同不存在");
        }
        if (conUserId != null && StrUtil.equals(ContractConstants.UN_SIGNED_FLAG, contract.getPartyASignFlag())) {
            return AjaxResult.error("甲方未签署,不能先签署");
        }
        if (!ProprietorContractEnum.CONTRACT_STATUS_SIGN.getValue().equals(contract.getContractStatus())) {
            return AjaxResult.error("合同状态异常，请刷新后再试");
        }
        if (ContractConstants.SIGNING_MODE_PAPER.equals(contract.getSigningMode())) {
            return AjaxResult.error("纸质合同不支持签约");
        }
        if (StrUtil.isBlank(contract.getFlowId())) {
            return AjaxResult.warn("该合同数据错误，无法签约");
        }
        if (ObjectUtil.isNotEmpty(conUserId)) {
            if (!contract.getProprietorUserId().equals(conUserId)) {
                return AjaxResult.error("非法操作");
            }
        }
        if (StrUtil.isNotBlank(proprietorContract.getTenantId())) {
            if (!contract.getTenantId().equals(proprietorContract.getTenantId())) {
                return AjaxResult.error("非法操作");
            }
        }

        String actorUrl = faDaDaService.getActorUrl(contract.getFlowId(), proprietorContract.getRedirectUrl(), ObjectUtil.isNotEmpty(conUserId));
        return StrUtil.isBlank(actorUrl) ? AjaxResult.error("数据异常，请联系管理员") : AjaxResult.success("操作成功", actorUrl);
    }

    @Override
    public void proprietorContractOverdueTask() {
        List<ProprietorContract> contractList = proprietorContractMapper.selectProprietorContractOverdueTask();
        if (CollectionUtil.isNotEmpty(contractList)) {

            List<String> ids = contractList.stream()
                    .map(ProprietorContract::getProprietorContractId).collect(Collectors.toList());
            proprietorContractMapper.updateBatchLesseeContractByStatus(ids, ProprietorContractEnum.CONTRACT_STATUS_OVERDUE.getValue());
        }
    }

    @Override
    public ProprietorContract selectProprietorContractByFlowId(String flowId) {
        return proprietorContractMapper.selectProprietorContractByFlowId(flowId);
    }

    private void packagingData(House house) {

        if (house.getHouseArea().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("面积需大于0");
        }
        if (HouseStateEnum.COOPERATION_TYPE_AGENCY.getValue().equals(house.getCooperationType())) {
            if (HouseStateEnum.CHARGE_TYPE_BILL.getValue().equals(house.getChargeType())) {
                if (house.getServiceCharge().scale() > 1) {
                    throw new ServiceException("账单服务费最多小数点后一位");
                }
                if (house.getServiceCharge().compareTo(new BigDecimal("100")) > 0) {
                    throw new ServiceException("账单服务费比例不能大于100");
                }
            } else {
                if (house.getFeeAmount().scale() > 2) {
                    throw new ServiceException("费用金额最多小数点后两位");
                }
                if (house.getFeeAmount().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new ServiceException("费用金额需大于0元");
                }
            }
        }

        if (house.getCheckInNumber() == 0) {
            throw new ServiceException("可住人数需大于0");
        }

        BizUserBusiness userBusiness = bizUserBusinessService.selectBizUserBusinessByUserId(house.getHouseManagerId(), house.getTenantId());
        if (ObjectUtil.isEmpty(userBusiness)) {
            throw new ServiceException("房管家不存在");
        }
        Proprietor proprietor = proprietorService.selectProprietorByConUserId(house.getProprietorUserId());
        if (ObjectUtil.isEmpty(proprietor)) {
            throw new ServiceException("业主不存在");
        }
        house.setHouseManagerName(userBusiness.getUserName());
        house.setHouseManagerPhone(userBusiness.getPhonenumber());
        house.setProprietorName(proprietor.getProprietorName());
        Estate estate = estateService.selectEstateByEstateId(house.getEstateId());
        house.setPremisesAddress(estate.getPremisesAddress());

        String premisesAddress = house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber() + "房";
        String fullAddress = estate.getProvinceName() + estate.getCityName() + estate.getDistrictName() + estate.getStreetName()
                + premisesAddress;
        house.setPremisesAddress(premisesAddress);
        house.setFullAddress(fullAddress);
        house.setProvinceId(estate.getProvinceId());
        house.setProvinceName(estate.getProvinceName());
        house.setCityId(estate.getCityId());
        house.setCityName(estate.getCityName());
        house.setDistrictId(estate.getDistrictId());
        house.setDistrictName(estate.getDistrictName());
        house.setStreetId(estate.getStreetId());
        house.setStreetName(estate.getStreetName());
        house.setCommunityId(estate.getCommunityId());
        house.setCommunityName(estate.getCommunityName());
    }
}
